﻿using System;

public class Mapper064 : MapperDefault
{
    private int irq_counter;
    private bool irq_enabled;
    private int irq_latch;
    internal int[] regs = new int[3];

    public override void init(NES nes)
    {
        base.init(nes);
        this.reset();
    }

    public override void loadROM(ROM rom)
    {
        if (rom.Valid)
        {
            int num = rom.VromBankCount * 4;
            int num2 = rom.RomBankCount * 2;
            this.load8kRomBank(0, 0x8000);
            this.load8kRomBank(1, 0xa000);
            this.load8kRomBank(num2 - 2, 0xc000);
            this.load8kRomBank(num2 - 1, 0xe000);
            this.load8kVromBank(0, 0);
            Console.Out.WriteLine("CHR = " + num);
            base.nes.Cpu.requestIrq(2);
        }
    }

    public override void reset()
    {
        this.irq_latch = 0;
        this.irq_counter = 0;
        this.irq_enabled = false;
        this.regs[0] = 0;
        this.regs[1] = 0;
        this.regs[2] = 0;
    }

    public override int syncH(int scanline)
    {
        if (((this.irq_enabled && (scanline >= 0)) && ((scanline <= 0xef) && ((base.ppu.scanline & 0x18) != 0))) && (--this.irq_counter == 0))
        {
            this.irq_counter = this.irq_latch;
            return 3;
        }
        return 0;
    }

    public override void write(int address, short value_Renamed)
    {
        if (address < 0x8000)
        {
            base.write(address, value_Renamed);
        }
        else
        {
            switch ((address & 0xf003))
            {
                case 0xc000:
                    this.irq_latch = value_Renamed;
                    this.irq_counter = this.irq_latch;
                    return;

                case 0xc001:
                    this.irq_counter = this.irq_latch;
                    return;

                case 0xe000:
                    this.irq_enabled = false;
                    this.irq_counter = this.irq_latch;
                    return;

                case 0xe001:
                    this.irq_enabled = true;
                    this.irq_counter = this.irq_latch;
                    break;

                case 0x8000:
                    this.regs[0] = value_Renamed & 15;
                    this.regs[1] = value_Renamed & 0x40;
                    this.regs[2] = value_Renamed & 0x80;
                    return;

                case 0x8001:
                    switch (this.regs[0])
                    {
                        case 0:
                            if (this.regs[2] != 0)
                            {
                                this.load2kVromBank(value_Renamed, 0x1000);
                                return;
                            }
                            this.load2kVromBank(value_Renamed, 0);
                            return;

                        case 1:
                            if (this.regs[2] != 0)
                            {
                                this.load2kVromBank(value_Renamed, 0x1800);
                                return;
                            }
                            this.load2kVromBank(value_Renamed, 0x800);
                            return;

                        case 2:
                            if (this.regs[2] != 0)
                            {
                                this.load1kVromBank(value_Renamed, 0);
                                return;
                            }
                            this.load1kVromBank(value_Renamed, 0x1000);
                            return;

                        case 3:
                            if (this.regs[2] != 0)
                            {
                                this.load1kVromBank(value_Renamed, 0x400);
                                return;
                            }
                            this.load1kVromBank(value_Renamed, 0x1400);
                            return;

                        case 4:
                            if (this.regs[2] != 0)
                            {
                                this.load1kVromBank(value_Renamed, 0x800);
                                return;
                            }
                            this.load1kVromBank(value_Renamed, 0x1800);
                            return;

                        case 5:
                            if (this.regs[2] != 0)
                            {
                                this.load1kVromBank(value_Renamed, 0xc00);
                                return;
                            }
                            this.load1kVromBank(value_Renamed, 0x1c00);
                            return;

                        case 6:
                            if (this.regs[1] != 0)
                            {
                                this.load8kRomBank(value_Renamed, 0xa000);
                                return;
                            }
                            this.load8kRomBank(value_Renamed, 0x8000);
                            return;

                        case 7:
                            if (this.regs[1] != 0)
                            {
                                this.load8kRomBank(value_Renamed, 0xc000);
                                return;
                            }
                            this.load8kRomBank(value_Renamed, 0xa000);
                            return;

                        case 8:
                            this.load1kVromBank(value_Renamed, 0x400);
                            return;

                        case 9:
                            this.load1kVromBank(value_Renamed, 0xc00);
                            return;

                        case 15:
                            if (this.regs[1] != 0)
                            {
                                this.load8kRomBank(value_Renamed, 0x8000);
                                return;
                            }
                            this.load8kRomBank(value_Renamed, 0xc000);
                            return;
                    }
                    return;

                case 0xa000:
                    if ((value_Renamed & 1) == 0)
                    {
                        base.nes.Ppu.Mirroring = 0;
                        return;
                    }
                    base.nes.Ppu.Mirroring = 1;
                    return;

                default:
                    return;
            }
        }
    }
}

